﻿using AssetsSys.Dto;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using AssetsSys.BLL.AutoMapper;
using AssetsSys.DAL;
using AssetsSys.Dto.Assets;
using AssetsSys.Dto.Modify;
using AssetsSys.model;
using AutoMapper.Internal;

namespace AssetsSys.BLL
{
    /// <summary>
    /// 固定资产
    /// </summary>
    public class AssetsManger
    {
        /// <summary>
        /// 获取所有资产
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static async Task<PageModel> GetAssetsList(AssetsQuertDto request)
        {
            using (var assSvc = new AssetsService())
            {
                Expression<Func<Assets, bool>> predicate = (x => request.StatusName.Contains(x.Status.StatusName)
                                                                 && (request.StatusId == Guid.Empty || x.StatusId == request.StatusId)
                                                                 && (request.AssetsNum == null || x.AssetsNum.Contains(request.AssetsNum))
                                                                 && (request.AssetsName == null || x.AssetsName.Contains(request.AssetsName))
                                                                 && (request.DecimalMin == 0 || x.Decimal >= request.DecimalMin)
                                                                 && (request.DecimalMax == 0 || x.Decimal <= request.DecimalMax)
                                                                 && (request.TypeId == Guid.Empty || x.TypeId== request.TypeId)
                                                                 && (request.SourceId == Guid.Empty || x.SourceId==request.SourceId)
                                                                 && (request.PrincipalUserId == Guid.Empty || x.PrincipalUser.Id == request.PrincipalUserId)
                                                                 && (request.PrincipalDepartmentId == Guid.Empty || x.PrincipalUser.Department.Id==request.PrincipalDepartmentId)
                                                                 && (request.StorageUserId == Guid.Empty || x.StorageUser.Id == request.StorageUserId)
                                                                 && (request.StorageDepartmentId == Guid.Empty || x.StorageUser.Department.Id == request.StorageDepartmentId));
                var totalCount = (await assSvc.GetAll(predicate, true).ToListAsync()).Count;
                var assetsList = await assSvc.GetAll(predicate, false, request.PageIndex, request.PageSize)
                    .Select(x => new AssetsResponseModel
                    {
                        Id = x.Id,
                        AssetsNum = x.AssetsNum,
                        AssetsName = x.AssetsName,
                        AssetsDescribe = x.AssetsDescribe,
                        Decimal = x.Decimal,
                        Type = x.Type.TypeName,
                        AgeLimit = x.Type.AgeLimit,
                        Source = x.Source.SourceName,
                        Status = x.Status.StatusName,
                        PrincipalUser = x.PrincipalUser.UserName,
                        PrincipalDepartment = x.PrincipalUser.Department.DepartmentName,
                        StorageUser = x.StorageUser.UserName,
                        StorageDepartment = x.StorageUser.Department.DepartmentName,
                        CreateTime = x.CreateTime
                    }).ToListAsync();
                return new PageModel()
                {
                    Count = totalCount,
                    Data = assetsList
                };
            }
        }

        /// <summary>
        /// 获取当前部门资产
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static async Task<PageModel> GetMyDepartmentAssetsList(AssetsQuertDto request)
        {
            Guid departmentId;
            using (var useSvc = new UserService())
            {
                departmentId = (await useSvc.GetAll(x => x.Id == request.UserId).FirstOrDefaultAsync()).DepartmentId;
            }
            using (var assSvc = new AssetsService())
            {
                Expression<Func<Assets, bool>> predicate = (x => x.PrincipalUser.DepartmentId == departmentId
                && request.StatusName.Contains(x.Status.StatusName)
                && (request.AssetsNum == null || x.AssetsNum.Contains(request.AssetsNum))
                && (request.AssetsName == null || x.AssetsName.Contains(request.AssetsName)));
                var totalCount = (await assSvc.GetAll(predicate, true).ToListAsync()).Count;
                var assetsList = await assSvc.GetAll(predicate, false, request.PageIndex, request.PageSize)
                    .OrderByDescending(x => x.CreateTime).Select(x => new AssetsResponseModel()
                    {
                        Id = x.Id,
                        AssetsNum = x.AssetsNum,
                        AssetsName = x.AssetsName,
                        AssetsDescribe = x.AssetsDescribe,
                        Decimal = x.Decimal,
                        Type = x.Type.TypeName,
                        AgeLimit = x.Type.AgeLimit,
                        Source = x.Source.SourceName,
                        Status = x.Status.StatusName,
                        PrincipalUser = x.PrincipalUser.UserName,
                        PrincipalDepartment = x.PrincipalUser.Department.DepartmentName,
                        StorageUser = x.StorageUser.UserName,
                        StorageDepartment = x.StorageUser.Department.DepartmentName
                    }).ToListAsync();
                return new PageModel()
                {
                    Count = totalCount,
                    Data = assetsList
                };
            }
        }

        /// <summary>
        /// 添加资产信息
        /// </summary>
        /// <param name="assetsName"></param>
        /// <param name="assetsDescribe"></param>
        /// <param name="decimal"></param>
        /// <param name="sourceId"></param>
        /// <param name="statusId"></param>
        /// <param name="typeId"></param>
        /// <param name="typeCode"></param>
        /// <param name="principalUserId"></param>
        /// <param name="storageUserId"></param>
        /// <returns></returns>
        public static async Task<bool> CreateAssets(string assetsName, string assetsDescribe,
            decimal @decimal, Guid sourceId, Guid statusId, Guid typeId, int typeCode, Guid principalUserId, Guid storageUserId)
        {
            using (var assSvc = new AssetsService())
            {
                var date = DateTime.Now;
                var nowYear = date.Year.ToString().Substring(2, 2);
                var nowMonth = date.Month<10? date.Month.ToString().PadLeft(2, '0') : date.Month.ToString();
                var assetsNum = nowYear + nowMonth;
                var count = (await assSvc.GetAll(x=>x.AssetsNum.Substring(1).StartsWith(assetsNum), true).ToListAsync()).Count + 1;
                var countstr = "";
                if (count > 999){countstr = "a"+ (count-999).ToString().PadLeft(3, '0');}
                else{countstr = count.ToString().PadLeft(4, '0');}
                assetsNum = typeCode+ assetsNum + countstr;
                await assSvc.CreateAsync(new Assets()
                {
                    AssetsName = assetsName,
                    AssetsDescribe = assetsDescribe,
                    AssetsNum = assetsNum,
                    Decimal = @decimal,
                    TypeId = typeId,
                    SourceId = sourceId,
                    StatusId = statusId,
                    PrincipalId = principalUserId,
                    StorageId = storageUserId
                });
                return true;
            }
        }

        /// <summary>
        /// 获取资产信息
        /// </summary>
        /// <param name="assetsid"></param>
        /// <returns></returns>
        public static async Task<AssetsModel> GetById(Guid assetsid)
        {
            using (var assSvc = new AssetsService())
            {
                return (await assSvc.GetOne(assetsid)).MapTo<AssetsModel>();
            }
        }

        /// <summary>
        /// 修改资产信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static async Task<bool> Update(AssetsModel model)
        {
            using (var assSvc = new AssetsService())
            {
                var oldModel = await assSvc.GetOne(model.Id);
                if (oldModel == null)
                {
                    return false;
                }
                oldModel.AssetsName = model.AssetsName ?? oldModel.AssetsName;
                oldModel.AssetsDescribe = model.AssetsDescribe ?? oldModel.AssetsDescribe;
                oldModel.Decimal = model.Decimal == 0 ? oldModel.Decimal:model.Decimal;
                oldModel.SourceId = model.SourceId == Guid.Empty ? oldModel.SourceId : model.SourceId;
                oldModel.StatusId = model.StatusId == Guid.Empty ? oldModel.StatusId : model.StatusId; 
                oldModel.TypeId = model.TypeId == Guid.Empty ? oldModel.TypeId : model.TypeId;
                oldModel.PrincipalId = model.PrincipalId == Guid.Empty ? oldModel.PrincipalId : model.PrincipalId;
                await assSvc.EditAsvnc(oldModel);
            }
            return true;
        }

        /// <summary>
        /// 获取资产统计数量
        /// </summary>
        /// <returns></returns>
        public static async Task<List<CountModel>> GetCountInfo()
        {
            
            using (var assSvc = new AssetsService())
            {
                var countNum = new List<CountModel>();
                var assetsList = await assSvc.GetAll().Select(x => new AssetsResponseModel
                    {
                        Id = x.Id,
                        AssetsNum = x.AssetsNum,
                        AssetsName = x.AssetsName,
                        AssetsDescribe = x.AssetsDescribe,
                        Decimal = x.Decimal,
                        Type = x.Type.TypeName,
                        AgeLimit = x.Type.AgeLimit,
                        Source = x.Source.SourceName,
                        Status = x.Status.StatusName,
                        PrincipalUser = x.PrincipalUser.UserName,
                        PrincipalDepartment = x.PrincipalUser.Department.DepartmentName,
                        StorageUser = x.StorageUser.UserName,
                        StorageDepartment = x.StorageUser.Department.DepartmentName,
                        CreateTime = x.CreateTime
                    }).ToListAsync();
                //本月新增
                var date = DateTime.Now;
                var nowYear = date.Year.ToString().Substring(2, 2);
                var nowMonth = date.Month < 10 ? date.Month.ToString().PadLeft(2, '0') : date.Month.ToString();
                var assetsNum = nowYear + nowMonth;
                var monthAddNum = assetsList.Where(x => x.AssetsNum.Substring(1, 4) == assetsNum).Count();
                countNum.Add(new CountModel()
                {
                    CountName = "本月新增",
                    CountNum = monthAddNum.ToString(),
                    Units = "件"
                });
                //资产总数
                var status=new List<string>()
                {
                    "资产处置",
                    "遗失"
                };
                var allNum = assetsList.Count(x => status.IndexOf(x.Status) < 0);
                countNum.Add(new CountModel()
                {
                    CountName = "资产总数",
                    CountNum = allNum.ToString(),
                    Units = "件"
                });
                //资产价值
                var allDecimal = assetsList.Sum(x => x.Decimal);
                countNum.Add(new CountModel()
                {
                    CountName = "资产价值",
                    CountNum = allDecimal.ToString(CultureInfo.CurrentCulture),
                    Units = "元"
                });
                //正常资产
                var normalStatus = new List<string>()
                {
                    "正常",
                    "闲置",
                    "内部转移"
                };
                var normalNum = assetsList.Count(x => normalStatus.Contains(x.Status));
                countNum.Add(new CountModel()
                {
                    CountName = "正常资产",
                    CountNum = normalNum.ToString(),
                    Units = "件"
                });
                //故障资产
                var breakdownStatus = new List<string>()
                {
                    "故障"
                };
                var breakdownNum = assetsList.Count(x => breakdownStatus.Contains(x.Status));
                countNum.Add(new CountModel()
                {
                    CountName = "故障资产",
                    CountNum = breakdownNum.ToString(),
                    Units = "件"
                });
                //余龄资产 
                var oldStatus = new List<string>()
                {
                    "资产处置",
                    "遗失"
                };
                var oldNum = assetsList.Count(x => oldStatus.IndexOf(x.Status) < 0&&x.CreateTime.AddYears(x.AgeLimit)<DateTime.Now);
                countNum.Add(new CountModel()
                {
                    CountName = "余龄资产",
                    CountNum = oldNum.ToString(),
                    Units = "件"
                });

                return countNum;
            }
            
        }
    }
}
